import 'dart:async';
import 'dart:collection';
import 'package:df/page/login/login.dart';
import 'package:df/page/login/login_page.dart';
import 'package:df/page/web/js_callback.dart';
import 'package:df/page/web/permission_key.dart';
import 'package:df/page/web/web_constant.dart';
import 'package:df/page/web/web_page.dart';
import 'package:df/utils/logger_utils.dart';
import 'package:df/widgets/toast_utils.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:go_router/go_router.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:url_launcher/url_launcher.dart';
import 'dart:io';
import 'package:df/generated/l10n.dart';


class ScanPage extends StatefulWidget {

  const ScanPage({Key? key, }) : super(key: key);

  @override
  State<StatefulWidget> createState() {
    String url = Web.oldWechatScanUrl;
    LogUtils.w('【浏览器】最终地址= ' + url);
    return _ScanPageState(url);
  }
}

class _ScanPageState extends State<ScanPage> {
  final String scanUrl;
  _ScanPageState(this.scanUrl);

  final GlobalKey webViewKey = GlobalKey();
  double progress = 0;
  final urlController = TextEditingController();
  PullToRefreshController? pullToRefreshController;
  InAppWebViewController? inAppWebViewController;
  InAppWebViewSettings settings = kInAppWebViewSettings;


  @override
  void initState() {
    super.initState();

    pullToRefreshController = kIsWeb || ![TargetPlatform.iOS, TargetPlatform.android].contains(defaultTargetPlatform)
        ? null
        : PullToRefreshController(
      settings: PullToRefreshSettings(
        color: Colors.cyan,
      ),
      onRefresh: () async {
        if (defaultTargetPlatform == TargetPlatform.android) {
          inAppWebViewController?.reload();
        } else if (defaultTargetPlatform == TargetPlatform.iOS) {
          inAppWebViewController?.loadUrl(urlRequest: URLRequest(url: await inAppWebViewController?.getUrl()));
        }
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return buildScaffold1(context);
  }

  Widget buildScaffold1(BuildContext context) {
    return

      Scaffold(
        appBar: AppBar(
            title: Text(S.current.wechatScanLogin),
            leading: IconButton(
              icon: Icon(Icons.arrow_back),
              onPressed: () {
                GoRouter.of(context).pop();
              },
            ),
        ),

        body: buildSafeArea2(context),
      );
  }

  Widget buildSafeArea2(BuildContext context) {
    return SafeArea(
      top: true,
      bottom: false,
      left: false,
      right: false,

      child: Stack(
        children: [
          buildInAppWebView5(context),
          (progress < 1.0) ? LinearProgressIndicator(value: progress) : Container(),
        ],
      ),
    );
  }

  Widget buildInAppWebView5(BuildContext context) {
    final Completer<InAppWebViewController> controllerCompleter = Completer<InAppWebViewController>();

    return InAppWebView(
      //【JsFlutter-2/2】==============================================
      initialUrlRequest: URLRequest(url: WebUri(scanUrl)),
      //【JsFlutter-2/2】==============================================
      // 禁用 SSL 证书验证，总是信任
      onReceivedServerTrustAuthRequest: (controller, challenge) async {
        return ServerTrustAuthResponse(action: ServerTrustAuthResponseAction.PROCEED);
      },

      onConsoleMessage: (controller, consoleMessage) {
        if (consoleMessage.message == 'Token过期') {
          return;
        }
        LogUtils.d(
            '=============================================================================================================='
                '\n【Js控制台】\n${consoleMessage}\n'
            '=============================================================================================================='
        );
      },
      onWebViewCreated: (controller) async {
        inAppWebViewController = controller;
        controllerCompleter.complete(controller);
        controllerCompleter.future.then((value) {

        });
        addJsHandler(context, controller);
      },
      initialUserScripts: UnmodifiableListView<UserScript>([]),
      key: webViewKey,
      pullToRefreshController: pullToRefreshController,
      initialSettings: settings,
      onLoadStart: (controller, url) async {
        setState(() {
          urlController.text = url.toString();
          LogUtils.w('【浏览器】Url= ${url.toString()}');
        });
      },
      onPermissionRequest: (controller, request) async {
        return PermissionResponse(//TODO 权限
            resources: request.resources,
            action: PermissionResponseAction.GRANT);
      },
      shouldOverrideUrlLoading:
          (controller, navigationAction) async {
        var uri = navigationAction.request.url!;
        if (!["http", "https", "file", "chrome", "data", "javascript", "about"
        ].contains(uri.scheme)) {
          if (await canLaunchUrl(uri)) {
            await launchUrl(
              uri,
            );
            // and cancel the request
            return NavigationActionPolicy.CANCEL;
          }
        }

        return NavigationActionPolicy.ALLOW;
      },
      onLoadStop: (controller, url) async {
        pullToRefreshController?.endRefreshing();
        setState(() {
          urlController.text = url.toString();
        });
        String? pageTitle = await controller.getTitle();
        LogUtils.w("【浏览器】标题= ${pageTitle}");
      },
      onReceivedError: (controller, request, error) {
        pullToRefreshController?.endRefreshing();
      },
      onProgressChanged: (controller, progress) {
        if (progress == 100) {
          pullToRefreshController?.endRefreshing();
        }
        setState(() {
          this.progress = progress / 100;
        });
      },
      onUpdateVisitedHistory: (controller, url, isReload) {
        setState(() {
          urlController.text = url.toString();
        });
      },
    );
  }

  /// https://blog.csdn.net/gloryFlow/article/details/133643136
  void addJsHandler(BuildContext context,InAppWebViewController? controller) {
    String platform = "";
    if (Platform.isAndroid) {
      platform = 'android';
    } else if (Platform.isIOS) {
      platform = 'ios';
    } else {
      platform = 'unknown';
    }

    String? wechatUnionId;
    String? flyUnionid;
    int loginType = -1;
    inAppWebViewController?.addJavaScriptHandler(handlerName: 'jsSetWxUnionId',
        callback: (parameters) async {
          //Js传给Flutter
          LogUtils.v('【Js->Flutter】扫码登录= ${parameters}');
          if (parameters.isNotEmpty) {
            try {
              Map<String, dynamic> jsData = parameters[0];
              String? platform = jsData['platform'];
              loginType = jsData['loginType'];
              wechatUnionId = jsData['wxUnionId'];
              flyUnionid = jsData['flyUnionid'];
              if(kDebugMode) {
                LogUtils.v('【Json】平台: ${platform}, 语言: ${wechatUnionId}');
                LogUtils.v('扫码登录\n微信: ${wechatUnionId}\n飞书: ${flyUnionid}');
              }
              Login login = Login(
                loginType: loginType,
                wxUnionId: wechatUnionId,
                flyUnionid: flyUnionid,
              );
              LoginPage.doLogin(login, context);
            } catch (e) {
              // 处理解析异常
              LogUtils.v('【Json】解码Js传参异常: ${e}');
              ToastUtils.show(S.current.scanLoginError);
            }
          }
          // Flutter返回给Js。
          return {'platform': platform, 'language': wechatUnionId};
        }
    );
  }


  Future<PermissionStatus>? requestCamera(String permissionKey) async {
    var status;
    if(PermissionKey.kCamera == permissionKey){
      status = await Permission.camera.request();
    } else {
      ToastUtils.show(S.current.noMatchThesePermissions);
    }
    return status;
  }

  //https://blog.csdn.net/Nean_Zhou/article/details/127172673
  Future<Map<Permission, PermissionStatus>> requestPermissions(List<String> permissionKeys) async {
    Map<Permission, PermissionStatus> statusMap = {};

    // for (Permission permission in permissionKeys[""]) {
    //   if (PermissionKey.kCamera == permission) {
    //       PermissionStatus status = await permission.request();
    //       statusMap[permission] = status;
    //   } else {
    //       ToastUtils.show(S.current.noMatchThesePermissions);
    //   }
    // }

    return statusMap;
  }

}

